/**
 * 
 */
package xyz.allin1.charlesloader;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.*;

import javassist.*;






/**
 * @author iYoungDone
 *
 */
public class CharlesMonitorTransformer implements ClassFileTransformer {

	/**
	 * 
	 */
	public CharlesMonitorTransformer() {
		// TODO Auto-generated constructor stub
	}

	/* (non-Javadoc)
	 * @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
	 * public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte classfileBuffer[])
	 */
	@Override
	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer)
			throws IllegalClassFormatException {
		// TODO Auto-generated method stub
		//System.out.println("(*^__^*) 变形金刚O(∩_∩)O~Transformer");
        //System.out.println("(*^__^*) Input Param className:"+className);
        className = className.replace("/", ".");
        CtClass ctClass = null;

        // if(!className.equals("com.xk72.charles.License"))
        //     return null;

        if(!className.equals("com.xk72.charles.slZe"))
        {
            return null;
        }

        try
        {
            System.out.println("(*^__^*) I Found className: " + className);

/*            //// 打印加载的这个类文件
    		ByteArrayInputStream is = new ByteArrayInputStream(classfileBuffer);
    		InputStreamReader input = new InputStreamReader(is);
    		BufferedReader bf = new BufferedReader(input);
    		String line = null;
    		
    		try {
    			while((line=bf.readLine()) != null){
    				System.out.println(line);
    				}
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		// 字节数组打印 
            System.out.println(Arrays.toString(classfileBuffer));*/

            // 注意:以下语句不执行可能是javassist.jar没有一起打包进jar包文件
            // 获取默认类型池对象
            ClassPool classPool = ClassPool.getDefault();
            // 没有执行到这里,注意javassist.jar放在同CharlesLoader目录下
            //System.out.println("classPool: " + classPool);
           
            // 获取指定的类文件
            ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
            
//            System.out.println("ctClass: " + ctClass);
//            System.out.println("classfileBuffer length: " + classfileBuffer.length);
//            System.out.println("toString: " + classfileBuffer.toString());
//            System.out.println(ctClass.getName());  // 获取类名
//            System.out.println("\tpackage " + ctClass.getPackageName());  // 获取包名
//            System.out.print("\t" + Modifier.toString(ctClass.getModifiers()) + " class " + ctClass.getSimpleName());  // 获取限定符和简要类名
//            System.out.println(" extends " + ctClass.getSuperclass().getName());  // 获取超类

            // This is v4.0.2 key
            //CtMethod a = ctClass.getDeclaredMethod("a", null);
            //a.setBody("return true;");
            //CtMethod ping = ctClass.getDeclaredMethod("b", null);
            //ping.setBody("return \"qtfreet00 www.qtfreet.com\";");

            // new v4.1.1 key
            System.out.println("(*^__^*) I am Working......");
            CtMethod ctm1 = ctClass.getDeclaredMethod("RrCt", null);
            ctm1.setBody("return true;");
            System.out.println("(*^__^*) ctm1 Done.");
            CtMethod ctm2 = ctClass.getDeclaredMethod("Vvni", null);
            ctm2.setBody("return \"iYoungDone Coded by B.S.O.D."
            +"\\r\\n  www.appleos.xyz \\r\\n❤ thanks to javassist,qtfreet00.\";");
            System.out.println("(*^__^*) ctm2 Done.");
            System.out.println("(*^__^*) All Done, Have Fun!!!");

            return ctClass.toBytecode();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return new byte[0];
    
        //return null;
	}

}
